-module(room).
-behaviour(gen_server).

-export([start_link/1, stop/0, init/1, terminate/2, code_change/3, handle_cast/2, handle_info/2, handle_call/3]).

-include("common.hrl").

-record(state, {id = 0,type=0,start_time=0,on_time_check=0,on_time_off=0,on_time_module=0,scene_model=0,script_items=[]}).
-define(SCENE_TIMER,100).


start_link(Data) ->
    gen_server:start_link(?MODULE, Data, []).

stop() ->
    gen_server:cast(?MODULE, stop).

%% init({Key,UsrInfoList,NeedUsrInfo,Scene,SceneData}) ->
%% UsrInfoList => [{Uid,Seq,Pos,_} | Next]
init({Sid,Acc,Req,RoomID,Psw,Seq}) ->
	?debug("init,{Sid,Acc,Req,RoomID,Psw,Seq} = ~p",[{Sid,Acc,Req,RoomID,Psw,Seq}]),
	put(id,RoomID),
	put(owner,Acc#account.id),
	put(req,Req),
	put(psw,Psw),	
	Ptm = lib_protocol:init_pt(),
	Ptm1 = regist_pt(Ptm),
	put(ptm,Ptm1),
	
	fun_room:inited(RoomID,Req),
	fun_room:join_room(Sid,Acc,Seq,true),
	{ok, #state{id = RoomID}}.


terminate(_Reason, #state{id =ID}) ->
	fun_room:destroyed(ID),
	ok.

code_change(_OldVsn, State, _Extra) ->    
    {ok, State}.

handle_call(_Request, _From, State) ->    
    {reply, ok, State}.

handle_info({timeout, TimerRef, CallBackInfo}, State) ->
	case CallBackInfo of
		{xtimer_callback, Call_BackInfo} ->
			?log("CallBackInfo..................=~p",[CallBackInfo]),
			try
				xtimer:on_timer(TimerRef, Call_BackInfo)
			catch E:R ->?log_error("timeout error,data=~p,E=~p,R=~p,stack=~p",[CallBackInfo,E,R,erlang:get_stacktrace()])
			end;
		{Module, Function} ->
			try
				Module:Function()
			catch E:R ->?log_error("timeout error,data=~p,E=~p,R=~p,stack=~p",[CallBackInfo,E,R,erlang:get_stacktrace()])
			end;
		{Module, Function, Args} ->
			try
				Module:Function(Args)
			catch E:R ->?log_error("timeout error,data=~p,E=~p,R=~p,stack=~p",[CallBackInfo,E,R,erlang:get_stacktrace()])
			end;	
		_ ->
			?log_warning("unknown timer callback,CallbackInfo=~p", [CallBackInfo])
	end,
	{noreply, State};


handle_info(Request, State) ->
	?debug("Request = ~p",[Request]),
	try
		fun_room:do_info(Request)
	catch E:R ->?log_error("info error,E=~p,R=~p,stack=~p",[E,R,erlang:get_stacktrace()])
	end,
    {noreply, State}.


handle_cast({recv, Sid, Data},State) ->
	?debug("Data = ~p",[Data]),
	try
		case lib_protocol:fill_pt(Data, get(ptm)) of
			{ok,Name,Seq,Pt} ->
				process_pt(Name,Seq,Pt,Sid);
			_R -> ?log_error("recv fill_pt error _R=~p,Data = ~p",[_R,Data])
		end
	catch E:R ->?log_error("recv error,E=~p,R=~p,stack=~p",[E,R,erlang:get_stacktrace()])
	end,
	{noreply, State};
handle_cast(stop, State) ->
	{stop, normal, State};
handle_cast(Msg, State) ->
%% 	?debug("Msg = ~p",[Msg]),
	try
		fun_room:do_msg(Msg)
	catch E:R ->?log_error("msg error,E=~p,R=~p,stack=~p",[E,R,erlang:get_stacktrace()])
	end,
	{noreply, State}.

get_pt_list()->
	[
	 pt_action_d001,
	 pt_action_int_d002,
	 pt_action_two_int_d012,
	 pt_action_three_int_d007
	].

regist_pt(Ptm) ->
	List = get_pt_list(),
	Fun = fun(Pt,Ptm) -> lib_protocol:regist_pt(Ptm, Pt) end,
	lists:foldl(Fun, Ptm, List).

process_pt(pt_action_d001,_Seq,Pt,Sid) -> 
	?debug("pt_action_d001 Pt = ~p,Sid = ~p",[Pt,Sid]),
	Action = Pt#pt_action.action,
	case db:dirty_get(ply, Sid) of
		[#ply{aid = Aid}] ->
			case Action of
				?ACTION_START_GAME-> fun_room:start();
				?ACTION_EXIT_ROOM-> fun_room:exit_room(Sid,Aid); 
				?ACTION_DESTORY_ROOM-> fun_room:destroy_room(Sid,Aid); 
				?ACTION_GAME_GUO -> fun_room:guo(Sid,Aid);
				?ACTION_GAME_HU->  fun_room:hu(Sid,Aid);
				?ACTION_SG_SIT_DOWN -> san_gong:sg_sit_down(Sid,Aid);
				?ACTION_SG_LIANG_PAI -> san_gong:start_liang_pai(Sid,Aid);
				?ACTION_SG_RETURN_LOBBY ->fun_room:return_lobby(Sid,Aid);
				_ -> skip
			end;
		_ -> skip
	end;

process_pt(pt_action_int_d002,_Seq,Pt,Sid) -> 
	?debug("pt_action_int_d002 Pt = ~p,Sid = ~p",[Pt,Sid]),
	Action = Pt#pt_action_int.action,
	case db:dirty_get(ply, Sid) of
		[#ply{aid = Aid}] ->
			case Action of
				?ACTION_GAME_OUT->  fun_room:out(Sid,Aid,Pt#pt_action_int.data);
				?ACTION_GAME_HU->  fun_room:hu(Sid,Aid,Pt#pt_action_int.data);
				?ACTION_GAME_GANG->  fun_room:gang(Sid,Aid,Pt#pt_action_int.data);
				?ACTION_SG_XIA_ZHU -> san_gong:player_start_xia_zhu(Sid,Aid,Pt#pt_action_int.data,get(zhuang));  
				?ACTION_SG_QIANG_ZHUANG -> san_gong:start_qiang_zhuang(Sid,Aid,Pt#pt_action_int.data);
				?ACTION_SG_REPLY_DESTROY_ROOM -> san_gong:player_reply_destroy_room(Sid,Aid,Pt#pt_action_int.data);
				_ -> skip
			end;
		_ -> skip
	end;
process_pt(pt_action_two_int_d012,_Seq,Pt,Sid) -> 
	?debug("pt_action_two_int_d012 Pt = ~p,Sid = ~p",[Pt,Sid]),
	Action = Pt#pt_action_two_int.action,
	case db:dirty_get(ply, Sid) of
		[#ply{aid = Aid}] ->
			case Action of
				?ACTION_GAME_CHI->  fun_room:chi(Sid,Aid,Pt#pt_action_two_int.data_One,
												 Pt#pt_action_two_int.data_Two);
				?ACTION_GAME_PENG->  fun_room:peng(Sid,Aid,Pt#pt_action_two_int.data_One,
												 Pt#pt_action_two_int.data_Two);
				?ACTION_GAME_GANG->  fun_room:gang(Sid,Aid,Pt#pt_action_two_int.data_One,
												 Pt#pt_action_two_int.data_Two);
				_ -> skip
			end;
		_ -> skip
	end;
process_pt(pt_action_three_int_d007,_Seq,Pt,Sid) -> 
	?debug("pt_action_three_int_d007 Pt = ~p,Sid = ~p",[Pt,Sid]),
	Action = Pt#pt_action_three_int.action,
	case db:dirty_get(ply, Sid) of
		[#ply{aid = Aid}] ->
			case Action of
				?ACTION_GAME_GANG->  fun_room:gang(Sid,Aid,Pt#pt_action_three_int.data_One,
												   Pt#pt_action_three_int.data_Two,Pt#pt_action_three_int.data_Three);
				_ -> skip
			end;
		_ -> skip
	end;
process_pt(_PtModule,_Seq,_Pt,_Sid) -> ok.